package com.alibaba.datax.core.util;

import org.apache.commons.codec.binary.Base64;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;


public class RSAUtils {

    /**
     * 公钥
     */
    public static String DEFAULT_PUBLIC_KEY = "rsapublickey";

    /**
     * 加密方法
     */
    private final static String ALGORITHM = "RSA";

    /**
     * 获取默认公钥
     */
    public static PublicKey getPublicKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(DEFAULT_PUBLIC_KEY));
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePublic(x509EncodedKeySpec);
    }

    /**
     * 获取指定公钥
     *
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    public static PublicKey getPublicKey(String pubKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decodeBase64(pubKey));
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePublic(x509EncodedKeySpec);
    }


    /**
     * 加密
     *
     * @param content 明文字符串
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     * @throws InvalidKeySpecException
     */
    public static String encrypt(String content) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException {
        PublicKey publicKey = getPublicKey();
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return new String(Base64.encodeBase64(cipher.doFinal(content.getBytes(StandardCharsets.UTF_8))));
    }


    /**
     * 加密
     *
     * @param content 明文字符串
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     * @throws InvalidKeySpecException
     */
    public static String encrypt(String content, String pubKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException {
        PublicKey publicKey = getPublicKey(pubKey);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return new String(Base64.encodeBase64(cipher.doFinal(content.getBytes(StandardCharsets.UTF_8))));
    }

    /**
     * 获取私钥
     *
     * @return
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeySpecException
     */
    public static PrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
        PKCS8EncodedKeySpec pics8EncodedKeySpec5 = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        return keyFactory.generatePrivate(pics8EncodedKeySpec5);
    }

    /**
     * 解密
     *
     * @param content 加密字符串
     * @param priKey  私钥
     * @return
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     * @throws InvalidKeySpecException
     */
    public static String decrypt(String content, String priKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, InvalidKeySpecException {
        PrivateKey privateKey = getPrivateKey(priKey);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        return new String(cipher.doFinal(Base64.decodeBase64(content)));
    }

    public static void main(String[] args) throws NoSuchPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, BadPaddingException, InvalidKeyException, InvalidKeySpecException {
        String enc = encrypt("1", "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCyXV5eYVYxJfFS78AdVGgUX80nrRXId2OpUJ5pFeN12Bon0Zq2sjPyWViwNWRjVyPoKru9xmKzGPLS4UO7J3mBfKzHSqoGLgYML2C7aDc/EXPDp/6pErLLgl180cjhNTR14Xl3hQW5Dr8V5M6BukcuztdtOUQ/CMOmVkFeDjDwewIDAQAB");
        System.out.println(enc);
        String dec = decrypt(enc, "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALJdXl5hVjEl8VLvwB1UaBRfzSetFch3Y6lQnmkV43XYGifRmrayM/JZWLA1ZGNXI+gqu73GYrMY8tLhQ7sneYF8rMdKqgYuBgwvYLtoNz8Rc8On/qkSssuCXXzRyOE1NHXheXeFBbkOvxXkzoG6Ry7O1205RD8Iw6ZWQV4OMPB7AgMBAAECgYBlgzQ5POakNDcDf8X0K1zM87U8NosmO6Sx8Vsm7bk2EZbZQLbv8b4U2Prb1pda3nZmJSQSnvz/d1yD3ocA1jeVIVUUEPhVPVVNFkF3Cq0I5Y/USAJFJAQjJRO71pwEO116PwDLmAVKwUFnhq7QKvvFMAq9kYSCrVQLnV3oDF+Z+QJBAOoOFU5ocGVSRCk+D3ub7vTm9nkIvIGjvQIzJV8l8Iz9S5PX1kVh7VF4pUJjVUsdB9gmmsJm//5QyvhbujULvL0CQQDDFpOUdtuYMAqTN4HJ3QUMdsVYs0yscu66bhrlYziJEjVNVD9H6Twm8Z20xqvbDT3955oe1UF/wP2pH7AzVWGXAkAlrmTBvdCyjz8IAMTPWrhq1zBBJiXrHShVzVQr8Fi86h6by7jkbLKfVjQM7x8RO7hClVx/BcQa9njm6SWeWqhlAkBQT2PzkzZ1IRnJXulUE2N3rREyoaUnvKygHKF/2ue0LcW5jrv6O36ivYZhnAO1Sm9Bre0ZUksDb4w86imcCEMDAkAdC7dQQPCElFsVIcIaw639LqPshy0J98t67z5NleTOnx1KvhpoG+7O92+PLNUWH+LmkiLuVRe0LNRY2vVVOk93");
        System.out.println(dec);
    }
}